function CustomScroll() {
	
}
CustomScroll.prototype = {
	init: function(element,opts) {
		this.element = element;
		this.prefix = "as-custom-scroll";
		this.initVars();
		this.decorate();
		this.addEvents();
	},
	initVars: function() {
		this.customScroll = as.create("<div class='"+this.prefix+"'></div>");
		this.scrollBar = as.create(
			"<div class='"+this.prefix+"-bar'>" + 
				"<span href='#' class='"+this.prefix+"-up-button'></span>"+
				"<div class='"+this.prefix+"-line'><div class='"+this.prefix+"er'></div></div>"+
				"<span href='#' class='"+this.prefix+"-down-button'></span>"+
			"</div"
		);
		this.upButton = as.$$("."+this.prefix+"-up-button",this.scrollBar);
		this.downButton = as.$$("."+this.prefix+"-down-button",this.scrollBar);
		this.scrollLine = as.$$("."+this.prefix+"-line",this.scrollBar);
		this.scroller = as.$$("."+this.prefix+"er",this.scrollBar);
		this.nowScrolling = false;
		this.scrollTime = 1500;
		this.steps = 30;
	},
	decorate: function() {
		this.element.className += (" "+this.prefix+"-wrapper");
		this.blockSelection(this.scrollBar);
		while(this.element.childNodes[0]) {
			node = this.element.childNodes[0];
			as.append(node.cloneNode(true),this.customScroll);
			as.remove(node);
		}
		as.append(this.customScroll,this.element);
		as.append(this.scrollBar,this.element);
		as.style(this.scrollBar,{height: this.element.offsetHeight+"px"});
		as.style(this.customScroll,{
			width: this.customScroll.offsetWidth - this.scrollBar.offsetWidth + "px",
			"padding-right": this.scrollBar.offsetWidth + "px",
			top: "0px"
		});
		as.style(this.scrollLine,{
			top: this.upButton.offsetHeight+"px",
			height: this.scrollBar.offsetHeight-this.upButton.offsetHeight-this.downButton.offsetHeight+"px"
		});
		as.style(this.scroller,{
			top: "0px",
			height: this.scrollLine.offsetHeight*this.scrollLine.offsetHeight/this.customScroll.offsetHeight+"px"
		});		
		/*** restrictions: ***/
		this.minScrollerTop = 0;
		this.maxScrollerTop = this.scrollLine.offsetHeight - this.scroller.offsetHeight;
		this.sq = this.maxScrollerTop/(this.customScroll.offsetHeight - this.scrollBar.offsetHeight);
		this.defaultScrollStep = this.customScroll.offsetHeight/this.steps*this.sq;
	},
	addEvents: function() {
		as.e.mousedown(this.upButton,function(){this.preScrollByButtons("up")},this);
		as.e.mousedown(this.downButton,function(){this.preScrollByButtons("down")},this);
		as.e.mousedown(this.scroller,function(e){this.preScrollByScroller(e)},this);
		as.e.mwheel(this.element,this.preScrollByMWheel,this);
		as.e.mousedown(this.scrollLine,this.preScrollByLine,this);
	},
	preScrollByScroller: function(e) {
		as.cancelEvent(e,true);
		this.blockSelection(this.element);
		var y = e.clientY + document.documentElement.scrollTop;
		var startScrollerTop = parseInt(this.scroller.style.top);
		document.onmouseup = as.bind(function() {
			document.onmousemove = "";
			//var xt = as.append("<a href='#'></a>",document.body);xt.focus();xt.blur();as.remove(xt);
			this.unblockSelection(this.element);
		},this);
		document.onmousemove = as.bind(function(e) {
			e = e || window.event;
			var nowScrollerTop = startScrollerTop + e.clientY + document.documentElement.scrollTop - y;
			this.scroll(nowScrollerTop);
		},this);
	},
	preScrollByButtons: function(direction) {
		as.bind(function() {
			this.nowScrolling = true;
			document.onmouseup = as.bind(function(){
				this.nowScrolling = false;
				document.onmouseup = '';
			},this);
			as.bind(function() {
				if (!this.nowScrolling) return;
				var currentScrollerTop = parseInt(this.scroller.style.top);
				var step = (direction == "up") ? currentScrollerTop-=this.defaultScrollStep : currentScrollerTop+=this.defaultScrollStep;
				this.scroll(currentScrollerTop);
				setTimeout(as.bind(arguments.callee,this),this.scrollTime/this.steps);
			},this)();
		},this)();
	},
	preScrollByMWheel: function(e,direction) {
		var currentScrollerTop = parseInt(this.scroller.style.top);
		var step = (direction == "up") ? currentScrollerTop-=this.defaultScrollStep*2 : currentScrollerTop+=this.defaultScrollStep*2;
		this.scroll(currentScrollerTop);
	},
	preScrollByLine: function(e) {
		var mouseY = e.clientY + document.documentElement.scrollTop;
		var scrollerXYWH = as.getElementPosition(this.scroller);
		var direction;
		if (mouseY > scrollerXYWH.top + scrollerXYWH.height) direction = "down";
		else if (mouseY < scrollerXYWH.top) direction = "up";		
		this.preScrollByButtons(direction);
		as.bind(function(){
			var scrollerXYWH = as.getElementPosition(this.scroller);
			if ((mouseY > scrollerXYWH.top && direction == "up") || (mouseY < scrollerXYWH.top + scrollerXYWH.height && direction == "down")) {
				this.nowScrolling = false;
				return;
			}
			setTimeout(as.bind(arguments.callee,this),100);
		},this)();
	},
	scroll: function(nowScrollerTop) {
		if (nowScrollerTop > this.maxScrollerTop) nowScrollerTop = this.maxScrollerTop;
		if (nowScrollerTop < this.minScrollerTop) nowScrollerTop = this.minScrollerTop;
		this.scroller.style.top = nowScrollerTop + "px";
		this.customScroll.style.top = -nowScrollerTop/this.sq + "px";
	},
	blockSelection: function(element) {
		element.onselectstart = function() {return false;};
		element.unselectable = "on";
		element.style.MozUserSelect = "none";
	},
	unblockSelection: function(element) {		
		element.onselectstart = "";
		element.unselectable = "off";
		element.style.MozUserSelect = "";
	}
}
CustomScroll = as.Plugin("customscroll",CustomScroll);